package com.ctrlspace.core.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import com.ctrlspace.model.User;
import com.ctrlspace.util.db.Database;

public class UserDao {

	private static final String CREATE_USER = "INSERT INTO users VALUES (NULL, ?, ?, ?, ?, ?, NOW(), 0)";
	private static final String USER_EXISTS = "SELECT * FROM users WHERE username = ? LIMIT 1";
	private static final String UPDATE_USER = "UPDATE users SET username = ?, email = ?, firstName = ?, lastName = ?, lastLogin = ?, lastIp = ? WHERE userId = ?";
	private static final String GET_USER_FROM_ID = "SELECT * FROM users WHERE userId = ?";
	private static final String GET_USER_FROM_CREDS = "SELECT * FROM users WHERE username = ? AND password = ?";

	public User createUser(String username, String password, String email,
			String firstName, String lastName) {
		User newUser = null;

		// TODO: Add exceptions
		Connection conn = Database.getInstance().getConnection();

		// Build query
		try {
			PreparedStatement st = conn.prepareStatement(CREATE_USER,
					PreparedStatement.RETURN_GENERATED_KEYS);

			st.setString(1, username);
			st.setString(2, password);
			st.setString(3, email);
			st.setString(4, firstName);
			st.setString(5, lastName);

			int affectedRows = st.executeUpdate();

			// Don't attempt to get keys if there is no affected row
			if (affectedRows > 0) {
				ResultSet keys = st.getGeneratedKeys();

				// Get key, return newUser
				if (keys.next()) {
					int userId = keys.getInt(1);

					newUser = new User();
					newUser.setId(userId);
					newUser.setUsername(username);
					newUser.setEmail(email);
					newUser.setFirstName(firstName);
					newUser.setLastName(lastName);

					return newUser;
				}
			}
		} catch (SQLException e) {
			// TODO: Add custom exception
			e.printStackTrace();
		}

		return newUser;
	}

	public boolean userExists(String username) {
		Connection conn = Database.getInstance().getConnection();

		try {
			PreparedStatement st = conn.prepareStatement(USER_EXISTS);
			st.setString(1, username);

			ResultSet rs = st.executeQuery();

			// User exists
			if (rs.next()) {
				return true;
			}
		} catch (SQLException e) {
			// Add custom exception
			e.printStackTrace();
		}

		return false;
	}

	public void updateUser(int id, String username, String email,
			String firstName, String lastName, Date lastLogin, long lastIp) {
		Connection conn = Database.getInstance().getConnection();

		try {
			PreparedStatement st = conn.prepareStatement(UPDATE_USER);
			st.setString(1, username);
			st.setString(2, email);
			st.setString(3, firstName);
			st.setString(4, lastName);
			st.setDate(5, new java.sql.Date(lastLogin.getTime()));
			st.setLong(6, lastIp);
			st.setInt(7, id);

			st.executeUpdate();
		} catch (SQLException e) {
			// TODO Add custom exception
			e.printStackTrace();
		}
	}

	public User getUser(int id) {
		User user = null;

		// TODO: Add exceptions
		Connection conn = Database.getInstance().getConnection();

		// Build query
		try {
			PreparedStatement st = conn.prepareStatement(GET_USER_FROM_ID);

			st.setInt(1, id);

			ResultSet rs = st.executeQuery();

			// Found result!
			if (rs.next()) {
				user = new User();
				user.setId(rs.getInt("userId"));
				user.setUsername(rs.getString("username"));
				user.setEmail(rs.getString("email"));
				user.setFirstName(rs.getString("firstName"));
				user.setLastName(rs.getString("lastName"));
				user.setLastLogin(rs.getDate("lastLogin"));
				user.setLastIp(rs.getInt("lastIp"));
				user.setActiveWorkspaceId(rs.getInt("activeWorkspaceId"));

				return user;
			}
		} catch (SQLException e) {
			// TODO: Add custom exception
			e.printStackTrace();
		}

		return user;
	}
	
	public User getUserFromCredentials(String username, String password) {
		User user = null;

		// TODO: Add exceptions
		Connection conn = Database.getInstance().getConnection();

		// Build query
		try {
			PreparedStatement st = conn.prepareStatement(GET_USER_FROM_CREDS);
			st.setString(1, username);
			st.setString(2, password);

			ResultSet rs = st.executeQuery();

			// Found result!
			if (rs.next()) {
				user = new User();
				user.setId(rs.getInt("userId"));
				user.setUsername(rs.getString("username"));
				user.setEmail(rs.getString("email"));
				user.setFirstName(rs.getString("firstName"));
				user.setLastName(rs.getString("lastName"));
				user.setLastLogin(rs.getDate("lastLogin"));
				user.setLastIp(rs.getInt("lastIp"));
				user.setActiveWorkspaceId(rs.getInt("activeWorkspaceId"));

				return user;
			}
		} catch (SQLException e) {
			// TODO: Add custom exception
			e.printStackTrace();
		}

		return user;
	}
}
